package com.gopay.webtest.util;

import java.io.File;
import java.io.FileInputStream;
import java.security.KeyFactory;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Date;
import java.util.Enumeration;

import org.apache.commons.codec.binary.Base64;
import org.apache.log4j.Logger;

import sun.misc.BASE64Encoder;

/**
 * @ApiUtil
 * @AUTHOR LIUYONG
 * @2016/9/14 13:56 www.gopay.com.cn Inc.All rights reserved.
 */
public class ApiUtil {
    private static Logger logger = Logger.getLogger(ApiUtil.class);
    
//    public static String apicertPath = "D://custAPIcert";
//    public static String gopayCer = "D://custAPIcert";

    public static String apicertPath = "/usr/local/ciecc/apicert";
    public static String gopayCer = "/usr/local/ciecc/apicert";




    /**
     * 签名算法
     */
    public static final String SIGN_ALGORITHMS = "SHA1WithRSA";

    private static String envName;


    /**
     * 获得私钥
     * @param strPfx
     * @param strPassword
     * @return
     */
    public static PrivateKey GetPvkformPfx(String strPfx, String strPassword){
        try {
            KeyStore ks = KeyStore.getInstance("PKCS12");
            FileInputStream fis = new FileInputStream(strPfx);
            ks.load(fis, strPassword.toCharArray());
            fis.close();
            Enumeration enumas = ks.aliases();
            String keyAlias = null;
            if (enumas.hasMoreElements())// we are readin just one certificate.
            {
                keyAlias = (String)enumas.nextElement();
            }
            PrivateKey prikey = (PrivateKey) ks.getKey(keyAlias, strPassword.toCharArray());
            return prikey;
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获得私钥字节数组
     * @param privateKey
     * @return
     */
    public static byte[] getPriveteKeyBytes(PrivateKey privateKey){
        return privateKey.getEncoded();
    }


    /**
     * 获得私钥的字符串
     * @param privateKey
     * @return
     */
    public static String getPrivateKeyStrs(byte[] privateKey){
        return Base64.encodeBase64String(privateKey);
    }

    /**
     * 签名
     * @param content
     * @param privateKey
     * @return
     */
    public static String sign(String content, String privateKey)
    {
        try
        {
            PKCS8EncodedKeySpec priPKCS8    = new PKCS8EncodedKeySpec( Base64.decodeBase64(privateKey) );
            KeyFactory keyf = KeyFactory.getInstance("RSA");
            PrivateKey priKey = keyf.generatePrivate(priPKCS8);
            java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS);
            signature.initSign(priKey);
            signature.update( content.getBytes());
            byte[] signed = signature.sign();
            return Base64.encodeBase64String(signed);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 验签
     * @param content       原串
     * @param sign          签名串
     * @return
     */

    public static boolean doCheck(String content, String sign)
    {
        try
        {
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            String gopayPublicKeyStr = getGopayPublicKey();
            byte[] encodedKey = Base64.decodeBase64(gopayPublicKeyStr);
            PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
            java.security.Signature signature = java.security.Signature
                    .getInstance(SIGN_ALGORITHMS);

            signature.initVerify(pubKey);
            System.out.println("国付宝下行，原串 = " + content);
            String md5Str = SignUtil.md5(content);
            System.out.println("国付宝下行，md5Str = " + md5Str);
            signature.update( md5Str.getBytes());
            System.out.println("国付宝下行通知报文验签");
            boolean bverify = signature.verify( Base64.decodeBase64(sign) );
            String strdate = DateUtils.format(new Date());
            System.out.println("国付宝下行通知报文验签结果"+ strdate+ " bverify = " + bverify);
            return bverify;
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return false;
    }

    public static boolean doCheckByPressureTest(String content, String sign,String publicKeyValue)
    {
        try
        {
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            byte[] encodedKey = Base64.decodeBase64(publicKeyValue);
            PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
            java.security.Signature signature = java.security.Signature
                    .getInstance(SIGN_ALGORITHMS);

            signature.initVerify(pubKey);
            signature.update( content.getBytes() );
            //System.out.println("国付宝下行通知报文验签");
            boolean bverify = signature.verify( Base64.decodeBase64(sign) );
            //System.out.println("国付宝下行通知报文验签结果"+ strdate+ " bverify = " + bverify);
            return bverify;
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return false;
    }

    //从cer文件中读取公钥
    public static String getGopayPublicKey() {
        try {
            CertificateFactory certificatefactory = CertificateFactory.getInstance("X.509");
//            InputStream bais = ApiUtil.class.getResourceAsStream("/国付宝服务器签名证书7060.cer");
            String filePath = gopayCer;
            if(envName.contains("newplatform")||envName.contains("生产环境")||envName.contains("prod")){
                filePath = filePath + File.separator + "prod" ;
            }else if(envName.contains("gray")||envName.contains("灰度机")){
                filePath = filePath + File.separator + "gray" ;
            }else if(envName.contains("mer")||envName.contains("商户接入测试环境")){
                filePath = filePath + File.separator + "mer" ;
            }else if(envName.contains("test")){
                filePath = filePath + File.separator + "test" ;
            }else if(envName.contains("bank")){
                filePath = filePath + File.separator + "bank" ;
            }else{
                filePath = filePath + File.separator + "prod" ;
            }
            System.out.println(String.format("当前环境名称envName=%s,filePath=%s", envName,filePath));
            logger.error(String.format("当前环境名称envName=%s,filePath=%s", envName,filePath));
            
            FileInputStream  bais = new FileInputStream(filePath+File.separator+"gopay.cer");
            X509Certificate Cert = (X509Certificate) certificatefactory.generateCertificate(bais);
            PublicKey pk = Cert.getPublicKey();
            BASE64Encoder bse = new BASE64Encoder();
//            System.out.println("pk:" + bse.encode(pk.getEncoded()));
            return bse.encode(pk.getEncoded());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }



    public static void main(String[] args) {


        System.out.println(getGopayPublicKey());


    }

    public static void setEnvName(String envName) {
        ApiUtil.envName = envName;
    }
}
